#include "EnemyMgr.h"

//-- A manager class to handle multiple enemies
EnemyMgr::EnemyMgr():mSpawnTimer(0), mMaxSpawnTime(240), mEnemyDamage(0.1f), mEnemiesDead(0){
	
	//-- Seed
	srand (time(NULL));

	//-- Define spawn points
	mSpawnPoint[0] = abfw::Vector3(-0.2,0.2,0.02);
	mSpawnPoint[1] = abfw::Vector3(0.2,0.2, 0.02);
	mSpawnPoint[2] = abfw::Vector3(-0.2,-0.02,0.02);
	mSpawnPoint[3] = abfw::Vector3(0.2,-0.2,0.02);

}

EnemyMgr::~EnemyMgr(){}

//-- A method for adding an enemy to the current enemy list
void EnemyMgr::AddEnemy(abfw::Mesh* mesh, abfw::Matrix44 origin)
{
	//-- Choose a random spawn point
	int spawn = rand()%4;

	//-- Set the enemy mesh and origin
	mEnemyMesh = mesh;
	mEnemyOrigin = origin;

	//-- add enemy
	Enemy* enemy = new Enemy();
	enemy->Init(mesh);
	enemy->SetLocalScale(abfw::Vector3(0.014195f, 0.014195f, 0.014195f));
	enemy->SetVelocity(abfw::Vector3(0.0009f, 0.0009f, 0.0009f));
	enemy->SetOrigin(origin);
	enemy->GetLocalTransform()->SetTranslation(mSpawnPoint[spawn]);

	//-- Add the new enemy to the current vector
	mCurrentEnemies.push_back(*enemy); 
}

//-- Returns the current vector of enemies
std::vector<Enemy>& EnemyMgr::GetEnemies()
{
	return mCurrentEnemies;
}

//-- Updates all enemies in the vector
void EnemyMgr::Update(abfw::Matrix44 origin, abfw::Vector3 playerPosition, Player* player)
{
	mSpawnTimer++;

	//-- Control spawning of enemies
	if (mSpawnTimer > mMaxSpawnTime)
	{
		AddEnemy(mEnemyMesh, mEnemyOrigin);
		mSpawnTimer = 0;
	}

	//-- Itertate through all enemies
	for ( std::vector<Enemy>::iterator mEnemyIterator = mCurrentEnemies.begin(); mEnemyIterator != mCurrentEnemies.end();)
		{

			//-- Get enemy position
			abfw::Vector3 enemyPosition = mEnemyIterator->GetLocalTransform()->GetTranslation();

			//-- Get enemy velocity 
			abfw::Vector3 velocity = mEnemyIterator->GetVelocity();

			//-- Calculate the target direction
			abfw::Vector3 moveDirection;
			moveDirection = playerPosition - enemyPosition;

			//-- Check for this enemy colliding with player
			if (CollisionDetection::AABB(mEnemyIterator->GetMeshInstance(), player->GetMeshInstance()))
			{
				//-- Decrease player health
				player->AddHealth(-0.1f);
			}

			//-- Normalise the move direction
			moveDirection.Normalise();

			//-- update the enemy position
			mEnemyIterator->GetLocalTransform()->SetTranslation(abfw::Vector3(enemyPosition.x + moveDirection.x * velocity.x,
																				enemyPosition.y + moveDirection.y * velocity.y,
																					enemyPosition.z));

		

			//-- Update the health bar transformation
			abfw::Matrix44 healthBarTransform =  *mEnemyIterator->GetLocalTransform() * origin;
			mEnemyIterator->SetTransform(mEnemyIterator->GetLocalScale() * *mEnemyIterator->GetLocalTransform() * origin);

			//-- Update health bar
			mEnemyIterator->UpdateHealthBar(healthBarTransform);

			//-- Check for dead enemies
			if (mEnemyIterator->IsDead())
			{
				//-- Increment enemy dead count which is equal to the players score
				mEnemiesDead += 1;

				//-- Increase game difficulty
				if (mMaxSpawnTime > 50)
				{
					mMaxSpawnTime -=1;
					SetEnemyDamage(-0.005f);
				}

				//-- Cleanup and delete enemy
				delete mEnemyIterator->mesh();
				mEnemyIterator->GetMeshInstance().set_mesh(NULL);
				
				mEnemyIterator = mCurrentEnemies.erase(mEnemyIterator);
			}
			else
			{
				//-- increment iterator
				mEnemyIterator++;
			}
	}
}
//-- draw
void EnemyMgr::Draw(abfw::Renderer3D* render3D, abfw::Colour defaultColour)
{
	
	for ( std::vector<Enemy>::iterator mEnemyIterator = mCurrentEnemies.begin(); mEnemyIterator != mCurrentEnemies.end(); ++mEnemyIterator )
	{
		//-- Draw enemy
		render3D->DrawMesh(mEnemyIterator->GetMeshInstance());
		//-- Draw health bar, setting colour in shader
		render3D->default_shader_data().set_ambient_light_colour(abfw::Colour(0,1,0,0));
		render3D->DrawMesh(mEnemyIterator->GetHealthBar().GetMeshInstance());
		render3D->default_shader_data().set_ambient_light_colour(defaultColour);
	}
	
}

void EnemyMgr::CleanUp()
{
	for ( std::vector<Enemy>::iterator mEnemyIterator = mCurrentEnemies.begin(); mEnemyIterator != mCurrentEnemies.end(); ++mEnemyIterator )
	{
		delete mEnemyIterator->mesh();
	}
}